<?php

namespace App\Controller;

use App\Repository\UsersRepository;
use Knp\Component\Pager\PaginatorInterface;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\HttpFoundation\JsonResponse;
use Symfony\Component\Routing\Annotation\Route;
use Symfony\Component\HttpFoundation\Request;

class UsersController extends AbstractController
{
    #[Route('/api/v1/users', name: 'app_users')]
    public function index(Request $request, UsersRepository $usersRepository, PaginatorInterface $paginator): JsonResponse
    {
        $page               = $request->query->getInt('page', 1);
        $limit              = $request->query->getInt('limit', 20);
        $isActive           = $request->query->getInt('is_active', 0);
        $isMember           = $request->query->getInt('is_member', 0);
        $userType           = $request->query->get('user_type', "0");
        $lastLoginTimeStart = $request->query->get('last_login_at_start', '');
        $lastLoginTimeEnd   = $request->query->get('last_login_at_end', '');

        // do some params check
        $checkRes = $this->checkParams($lastLoginTimeStart, $lastLoginTimeEnd, $limit, $page, $isActive, $isMember, $userType);
        if ($checkRes['errcode'] > 0) {
            return $this->response($checkRes['errcode'], $checkRes['msg']);
        }

        $cond = [
            'page'                => $page,
            'limit'               => $limit,
            'is_active'           => $isActive,
            'is_member'           => $isMember,
            'user_type'           => explode(",", $userType),
            'last_login_at_start' => $lastLoginTimeStart,
            'last_login_at_end'   => $lastLoginTimeEnd,
        ];

        $query = $usersRepository->findUsersQuery($cond);
        $res = $paginator->paginate($query, $page, $limit);
        return $this->response(0, 'success', ['list' => $res->getItems(), 'paginator' => [
            'total' => $res->getTotalItemCount(),
            'page' => $page,
            'limit' => $limit,
        ]]);
    }

    /**
     * check request params
     * @param $lastLoginTimeStart
     * @param $lastLoginTimeEnd
     * @param $limit
     * @param $page
     * @return array
     */
    private function checkParams($lastLoginTimeStart, $lastLoginTimeEnd, $limit = 20, $page = 1,
                                 $isActive = 0, $isMember = 0, $userType = "0") {
        if (!$lastLoginTimeStart || !$lastLoginTimeEnd
            || !strtotime($lastLoginTimeStart) || strtotime($lastLoginTimeStart) == -1
            || !strtotime($lastLoginTimeEnd) || strtotime($lastLoginTimeEnd) == -1
        ) {
            return [
                'errcode' => __LINE__,
                'msg' => 'params(last_login_time) error.',
            ];
        }

        $gapDays = (strtotime($lastLoginTimeEnd) - strtotime($lastLoginTimeStart)) / 86400;
        if ($gapDays > 365) {
            return [
                'errcode' => __LINE__,
                'msg' => 'Please limit the time frame to less than 1 year.',
            ];
        }

        if ($limit > 1000) {
            return [
                'errcode' => __LINE__,
                'msg' => 'Up to 1000 queries per page.',
            ];
        }

        if ($page <= 0) {
            return [
                'errcode' => __LINE__,
                'msg' => 'page show upper zero.',
            ];
        }

        if ($isActive < 0 || $isMember < 0) {
            return [
                'errcode' => __LINE__,
                'msg' => 'is_active,is_member params cannot be less than zero.',
            ];
        }

        if (count(explode(",", $userType)) <= 0) {
            return [
                'errcode' => __LINE__,
                'msg' => 'user_type param show be separated by `,`',
            ];
        }

        return [
            'errcode' => 0,
            'msg' => '',
        ];
    }

    /**
     * api return
     * @param $code int ,  if $code=0 is success else happened some error
     * @param $msg string , give some friendly tips to your users
     * @param $data array
     * @return mixed
     */
    private function response($code, $msg = '', $data = []) {
        return $this->json([
            'code' => $code,
            'msg' => $msg,
            'data' => $data,
        ]);
    }
}
